package com.sx.controller;

import com.sx.pojo.Person;
import com.sx.service.PersonService;
import com.sx.service.serviceImpl.PersonServiceImpl;
import com.sx.utils.CookieUtils;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;

import java.io.Serial;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    // 序列化版本号
    @Serial
    private static final long serialVersionUID = 1L;
    // 创建业务逻辑层对象
    private final PersonService personService = new PersonServiceImpl();

    private static final Logger logger = LogManager.getLogger(LoginServlet.class);

   /* @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        String username = request.getParameter("username");
        String password = request.getParameter("password");

        // 这里模拟连接数据库验证，实际应用中需替换为真实数据库操作
        if ("admin".equals(username) && "123456".equals(password)) {
            response.sendRedirect("success.jsp"); // 登录成功跳转到成功页面（需创建success.jsp）
        } else {
            request.setAttribute("errorMessage", "用户名或密码错误，请重新输入。");
            request.getRequestDispatcher("login.jsp").forward(request, response);
        }
    }*/

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    /**
     * 处理登录请求的 doPost 方法
     * 该方法接收 HttpServletRequest 和 HttpServletResponse 对象，用于处理用户登录请求
     * 它通过验证用户名和密码来确定用户身份，并相应地转发请求到主页或登录页
     *
     * @param req  包含用户请求数据的 HttpServletRequest 对象
     * @param resp 用于向用户发送响应的 HttpServletResponse 对象
     * @throws ServletException 如果 Servlet 发生错误
     * @throws IOException      如果发生输入或输出错误
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置请求编码
        req.setCharacterEncoding("UTF-8");
        // 设置响应内容类型
        resp.setContentType("text/html;charset=UTF-8");

        try {
            // 获取用户名和密码参数，并进行基本验证和清理
            String username = sanitizeInput(req.getParameter("username"));
            String password = sanitizeInput(req.getParameter("password"));

            if (username == null || password == null || username.isEmpty() || password.isEmpty()) {
                req.setAttribute("errorMessage", "用户名或密码不能为空。");
                req.getRequestDispatcher("login.jsp").forward(req, resp);
                return;
            }

            // 调用服务层方法，根据用户名和密码查找用户
            Person person = personService.findUserByStuCodeAndPassword(username, password);

            if (person != null) {
                // 如果用户存在，将用户信息存储在会话中，并转发请求到主页
                HttpSession session = req.getSession();
                session.setAttribute("person", person);
                //添加Cookie
                CookieUtils.addCookie("username", 60 * 60 * 24, req, resp, username, password);
                req.getRequestDispatcher("/jsp/index.jsp").forward(req, resp);

            } else {
                // 如果用户不存在，设置错误消息，并转发请求回到登录页
                req.setAttribute("errorMessage", "用户名或密码错误，请重新输入。");
                req.getRequestDispatcher("login.jsp").forward(req, resp);
            }
        } catch (Exception e) {
            // 记录异常日志
            logger.error("登录处理过程中发生异常: ", e);
            // 返回服务器错误响应
            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "服务器内部错误");
        }
    }

    /**
     * 对用户输入进行简单的清理和转义，以防止 XSS（跨站脚本）攻击
     * 此方法主要针对 HTML 中的特殊字符进行转义，将其转换为对应的 HTML 实体
     *
     * @param input 用户输入的字符串，可能包含 HTML 特殊字符
     * @return 转义后的字符串，如果输入为 null，则返回 null
     */
    private String sanitizeInput(String input) {
        if (input == null) {
            return null;
        }
        // 进行简单的 HTML 转义，防止 XSS 攻击
        return input.replaceAll("&", "&amp;")
                .replaceAll("<", "&lt;")
                .replaceAll(">", "&gt;")
                .replaceAll("\"", "&quot;")
                .replaceAll("'", "&#x27;")
                .replaceAll("/", "&#x2F;");
    }


}
